/*
 * Copyright 2008 - 2009 Lars Heuer (heuer[at]semagia.com). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.semagia.atomico.server.storage.impl;

import com.semagia.atomico.server.dm.ICollectionInfo;
import com.semagia.atomico.server.dm.IFragmentInfo;
import com.semagia.atomico.server.dm.ISnapshotInfo;
import com.semagia.atomico.server.storage.IStorage;
import com.semagia.atomico.server.storage.SortOrder;
import com.semagia.atomico.server.storage.StorageException;

/**
 * Abstract implementation of an unmodifiable {@link IStorage} that handles 
 * some common use cases.
 * <p>
 * This class exists for simplification purposes, concrete classes should
 * override as much as possible for performance purposes or implement 
 * {@link IStorage} directly.
 * </p>
 * 
 * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
 */
public abstract class AbstractStorage implements IStorage {

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#isModifiable()
     */
    @Override
    public boolean isModifiable() {
        return false;
    }

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#lastModification()
     */
    @Override
    public synchronized long lastModification() throws StorageException {
        for (ICollectionInfo info: getCollectionInfos(SortOrder.UPDATED_DESC)) {
            return info.getUpdated();
        }
        return System.currentTimeMillis();
    }

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#lastCollectionModification(java.lang.String)
     */
    @Override
    public long lastCollectionModification(final String collId) throws StorageException {
        return Math.max(lastFragmentModification(collId), lastSnapshotModification(collId));
    }

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#lastFragmentModification(java.lang.String)
     */
    @Override
    public synchronized long lastFragmentModification(final String collId) throws StorageException {
        for (IFragmentInfo info: getFragmentInfos(collId)) {
            return info.getUpdated();
        }
        return System.currentTimeMillis();
    }

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#lastSnapshotModification(java.lang.String)
     */
    @Override
    public synchronized long lastSnapshotModification(final String collId) throws StorageException {
        for (ISnapshotInfo info: getSnapshotInfos(collId)) {
            return info.getUpdated();
        }
        return System.currentTimeMillis();
    }

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#getSnapshotInfos(java.lang.String, com.semagia.atomico.server.storage.SortOrder)
     */
    @SuppressWarnings("unchecked")
    @Override
    public Iterable<ISnapshotInfo> getSnapshotInfos(String collectionId,
            SortOrder sortOrder) throws StorageException {
        return (Iterable<ISnapshotInfo>) getSnapshotInfos(collectionId);
    }

    /* (non-Javadoc)
     * @see com.semagia.atomico.server.storage.IStorage#getFragmentInfos(java.lang.String, com.semagia.atomico.server.storage.SortOrder)
     */
    @SuppressWarnings("unchecked")
    @Override
    public Iterable<IFragmentInfo> getFragmentInfos(String collectionId,
            SortOrder sortOrder) throws StorageException {
        return (Iterable<IFragmentInfo>) getFragmentInfos(collectionId);
    }

}
